#include <string.h>
#include <cmath>

#include "global.hpp"
#include "mesh.hpp"
#include "cgnslib.h"

using namespace std;
void Mesh::readOversetMeshTab(Mesh &msh)
{
    string oversetMeshTabFileName = inputCtrl.oversetMeshTabFileName;
    int iEx,iZone,ijkP[NDIM],iP,diLNode;

    // Read the mesh file
    m_fileStream.open(oversetMeshTabFileName, ios::in);
    if (!m_fileStream.is_open())
    {
        m_msg = "Cannot open the oversetMeshTab file: " + oversetMeshTabFileName;
        logCtrl.error(m_msg.c_str());
    }
    else
    {
        m_fileStream >> NEx >> NExNode;
        m_msg = "-------------- oversetMeshTab-------------";
        logCtrl.info(m_msg.c_str());
        m_msg= "NEx: " + to_string(NEx) + " NExNode: " + to_string(NExNode);
        logCtrl.info(m_msg.c_str());
        for (int i = 0; i < NEx; i++)
        {
            m_fileStream >> iEx >> exTab[i][0] >> exTab[i][1] >> nExNode[i] >> exTab[i][2];
            //CHENC to be modified
            exTab[i][0]=exTab[i][0]-1;
            exTab[i][1]=exTab[i][1]-1;
            if (exTab[i][2]==20){
                exTab[i][2]=0; 
            }
            else{
                exTab[i][2]=1; 
            }
        }
        idxExNode[0] = 0;
        for (int i = 1; i < NEx; i++)
        {
            idxExNode[i] = idxExNode[i-1]+ nExNode[i - 1];
        }
        m_msg = "iEx  srcZone  dstZone  nExNode  idxExNode";
        logCtrl.info(m_msg.c_str());
        for (int i = 0; i < NEx; i++)
        {
            m_msg = to_string(i) + "  " + to_string(exTab[i][0]) + "  " + to_string(exTab[i][1]) + "  " + to_string(nExNode[i]) + "  " + to_string(idxExNode[i]);
            logCtrl.info(m_msg.c_str());
        }
    }
    m_fileStream.close();
    //CHENC to be modified
    #ifndef _2D
    for (iZone=0;iZone<msh.NZone;++iZone){
        iP=0;
        for (ijkP[0]=-2;ijkP[0]<NORDER-2;ijkP[0]++)
        for (ijkP[1]=-2;ijkP[1]<NORDER-2;ijkP[1]++)
        for (ijkP[2]=-2;ijkP[2]<NORDER-2;ijkP[2]++){
            intrpList[iZone][iP]=ijkP[1]*msh.size[iZone][0]+ijkP[0];
            iP++;
        }
    }
    #else
    for (iZone=0;iZone<msh.NZone;++iZone){
        iP=0;
        for (ijkP[0]=-1;ijkP[0]<NORDER-1;ijkP[0]++)
        for (ijkP[1]=-1;ijkP[1]<NORDER-1;ijkP[1]++){
            intrpList[iZone][iP]=ijkP[1]*msh.size[iZone][0]+ijkP[0];
            iP++;
        }
    }
    #endif
    m_msg = "oversetMeshTab has been read.";
    logCtrl.info(m_msg.c_str());
}
void Mesh::readOversetMeshInfo(int iCPU, ExNode *enode, Mesh &msh)
{
    string oversetMeshInfoFileName = inputCtrl.oversetMeshInfoFileName;
    string str;
    stringstream ss;
    int iEx, iExNode;
    int srcZone, dstZone, isP2P;
    int iDim,ijk[NDIM],iPoint;

    m_fileStream.open(oversetMeshInfoFileName, ios::in);
    if (!m_fileStream.is_open())
    {
        m_msg = "Cannot open the oversetMeshInfo file: " + oversetMeshInfoFileName;
        logCtrl.error(m_msg.c_str());
    }
    for (iEx = 0; iEx < NEx; iEx++)
    {
        getline(m_fileStream, str);
        ss.str(str);
        ss >> srcZone>> dstZone>>isP2P;
        srcZone=srcZone-1;
        dstZone=dstZone-1;
        ss.clear();
        if (isP2P==20){
            isP2P=0; 
        }
        else{
            isP2P=1; 
        }
        if (srcZone != exTab[iEx][0] || dstZone != exTab[iEx][1] || isP2P != exTab[iEx][2])
        {
            m_msg = "Information from oversetMeshTab and oversetMeshInfo is inconsistant. iEx " + to_string(iEx);
            logCtrl.error(m_msg.c_str());
            m_msg = "oversetMeshInfo srcZone: " + to_string(srcZone) + " dstZone: " + to_string(dstZone) + " isP2P: " + to_string(isP2P);
            logCtrl.error(m_msg.c_str());
            m_msg = "oversetMeshTab  srcZone: " + to_string(exTab[iEx][0]) + " dstZone: " + to_string(exTab[iEx][1]) + " isP2P: " + to_string(exTab[iEx][2]);
            logCtrl.error(m_msg.c_str());
        }
        for (iExNode = idxExNode[iEx]; iExNode < idxExNode[iEx]+nExNode[iEx]; iExNode++)
        {
            getline(m_fileStream, str);
            ss.str(str);
            for (int iDim=0;iDim<NDIM;iDim++) {
                ss>>(enode+iExNode)->ijkDst[iDim];
                (enode+iExNode)->ijkDst[iDim]-=1;
            }
            for (iDim=0;iDim<NDIM;iDim++) ijk[iDim]=(enode+iExNode)->ijkDst[iDim];
            (enode+iExNode)->iLNodeDst=msh.caliLNode(dstZone,ijk);
            for (int iDim=0;iDim<NDIM;iDim++) {
                ss>>(enode+iExNode)->ijkSrc[iDim];
                (enode+iExNode)->ijkSrc[iDim]-=1;
            }
            for (iDim=0;iDim<NDIM;iDim++) ijk[iDim]=(enode+iExNode)->ijkSrc[iDim];
            (enode+iExNode)->iLNodeSrc=msh.caliLNode(srcZone,ijk);
            ss.clear();
            getline(m_fileStream, str);
            ss.str(str);
            for (int iPoint=0;iPoint<NINTRPL;iPoint++) ss>>(enode+iExNode)->interpCoe[iPoint];
            ss.clear();
        }
        getline(m_fileStream, str);
    }
    m_fileStream.close();
    m_msg = "oversetMeshInfo has been read.";
    logCtrl.info(m_msg.c_str());
}